home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / demos / OpenGL / stonehenge / Point.h < prev    next >
C/C++ Source or Header  |  1996-11-11  |  10KB  |  404 lines

  1. /*
  2.  * (c) Copyright 1993, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #ifndef POINT_H
  39. #define POINT_H
  40.  
  41. #ifndef POINT_EXTERN
  42. #define POINT_EXTERN extern
  43. #endif 
  44.  
  45. #include <math.h>
  46.  
  47. const float point_fudge = .000001;
  48.  
  49. class Point {
  50.  public:
  51.   inline Point operator=(Point a);
  52.   inline Point operator=(GLfloat *a);
  53.   inline Point operator+(Point a);
  54.   inline Point operator+=(Point a);
  55.   inline Point operator-(Point a);
  56.   // This takes a cross-product
  57.   inline Point operator*(Point b);
  58.   inline Point operator*(GLfloat b);
  59.   inline Point operator*=(GLfloat b);
  60.   inline Point operator/(GLfloat b);
  61.   inline Point operator/=(GLfloat b);
  62.   inline GLfloat& operator[](int index);
  63.   
  64.   inline void set(GLfloat x, GLfloat y, GLfloat z, GLfloat w = 1.0);
  65.   
  66.   inline GLfloat dist(Point b);
  67.   inline GLfloat dot(Point b);
  68.   inline GLfloat dot(GLfloat x, GLfloat y, GLfloat z);
  69.   inline GLfloat mag();
  70.   inline GLfloat magsquared();
  71.   inline Point unit();
  72.   inline void unitize();
  73.   
  74.   inline Point scale(Point p);
  75.   
  76.   // Angle is in RADIANS
  77.   inline Point rotate(Point axis, GLfloat angle);
  78.   inline Point rotate(Point axis, GLfloat c, GLfloat s);
  79.   inline void rotate_self(Point axis, GLfloat c, GLfloat s);
  80.   Point rotate_abouty(GLfloat c, GLfloat s);
  81.   Point rotate_aboutz(GLfloat c, GLfloat s);
  82.   
  83.   // Returns point projected through proj_pt into XY plane
  84.   // Does nothing if proj_pt - *this is parallel to XY plane
  85.   inline Point project(Point proj_pt);
  86.   inline void project_self(Point proj_pt);
  87.   inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz);
  88.   inline Point project_direction(Point direction);
  89.   inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z);
  90.   // This projects (px, py, pz) into this in direction (dx, dy, dz)
  91.   inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  92.                      GLfloat x, GLfloat y, GLfloat z);
  93.  
  94.   // Returns point projected through light and refracted into XY
  95.   // plane.  
  96.   // N is normal at point (ie normal at *this)
  97.   // I is the index of refraction
  98.   inline Point refract(Point light, Point N, GLfloat I);
  99.   void refract_self(Point light, Point N, GLfloat I);
  100.   Point refract_direction(Point light, Point N, GLfloat I);
  101.   
  102.   inline void glvertex();
  103.   inline void glnormal();
  104.   
  105.   void print();
  106.   void print(const char *format);
  107.   
  108.   GLfloat pt[4];
  109.  private:
  110. };
  111.  
  112. POINT_EXTERN Point val;
  113.  
  114. #define DOT(a, b) (a.pt[0]*b.pt[0] + a.pt[1]*b.pt[1] + a.pt[2]*b.pt[2])
  115. #define THIS_DOT(b) (pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2])
  116.  
  117. inline Point Point::operator=(Point a)
  118. {
  119.   pt[0] = a.pt[0];
  120.   pt[1] = a.pt[1];
  121.   pt[2] = a.pt[2];
  122.   pt[3] = a.pt[3];
  123.   return *this;
  124. }
  125.  
  126. inline Point Point::operator=(GLfloat *a)
  127. {
  128.   pt[0] = a[0]; 
  129.   pt[1] = a[1]; 
  130.   pt[2] = a[2]; 
  131.   pt[3] = 1;
  132.   return *this;
  133. }
  134.  
  135. inline Point Point::operator+(Point a)
  136. {  
  137.   val.pt[0] = pt[0] + a.pt[0];
  138.   val.pt[1] = pt[1] + a.pt[1];
  139.   val.pt[2] = pt[2] + a.pt[2]; 
  140.   return val; 
  141. }
  142.  
  143. inline Point Point::operator+=(Point a)
  144. {
  145.   pt[0] += a.pt[0];
  146.   pt[1] += a.pt[1];
  147.   pt[2] += a.pt[2];
  148.   return *this;
  149. }
  150.  
  151. inline Point Point::operator-(Point a)
  152. {
  153.   val.pt[0] = pt[0] - a.pt[0];
  154.   val.pt[1] = pt[1] - a.pt[1];
  155.   val.pt[2] = pt[2] - a.pt[2];
  156.   return val;
  157. }
  158.   
  159. inline Point Point::operator*(Point b)
  160. {
  161.   val.pt[0] = pt[1]*b.pt[2] - b.pt[1]*pt[2];
  162.   val.pt[1] = pt[2]*b.pt[0] - b.pt[2]*pt[0];
  163.   val.pt[2] = pt[0]*b.pt[1] - pt[1]*b.pt[0];
  164.   return val;
  165. }
  166.  
  167. inline Point Point::operator*(GLfloat b)
  168. {
  169.   val.pt[0] = pt[0] * b;
  170.   val.pt[1] = pt[1] * b;
  171.   val.pt[2] = pt[2] * b;
  172.   return val;
  173. }
  174.  
  175. inline Point Point::operator*=(GLfloat b)
  176. {
  177.   pt[0] *= b;
  178.   pt[1] *= b;
  179.   pt[2] *= b;
  180.   return *this;
  181. }
  182.  
  183. inline Point Point::operator/(GLfloat b)
  184. {
  185.   val.pt[0] = pt[0] / b;
  186.   val.pt[1] = pt[1] / b;
  187.   val.pt[2] = pt[2] / b;
  188.   return val;
  189. }
  190.  
  191. inline Point Point::operator/=(GLfloat b)
  192. {
  193.   pt[0] /= b;
  194.   pt[1] /= b;
  195.   pt[2] /= b;
  196.   return *this;
  197. }
  198.  
  199. inline GLfloat& Point::operator[](int index)
  200. {
  201.   return pt[index];
  202. }
  203.  
  204. inline void Point::set(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  205. {
  206.   pt[0] = x;
  207.   pt[1] = y;
  208.   pt[2] = z;
  209.   pt[3] = w;
  210. }
  211.  
  212. inline GLfloat Point::dist(Point b)
  213. {
  214.   return (*this - b).mag();
  215. }
  216.  
  217. inline GLfloat Point::dot(Point b)
  218. {
  219.   return pt[0]*b.pt[0] + pt[1]*b.pt[1] + pt[2]*b.pt[2];
  220. }
  221.  
  222. inline GLfloat Point::dot(GLfloat x, GLfloat y, GLfloat z)
  223.   return pt[0]*x + pt[1]*y + pt[2]*z;
  224. }
  225.  
  226. inline GLfloat Point::mag()
  227. {
  228.   return sqrt(pt[0]*pt[0] + pt[1]*pt[1] + 
  229.               pt[2]*pt[2]);
  230. }
  231.  
  232. inline GLfloat Point::magsquared()
  233. {
  234.   return pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2];
  235. }
  236.  
  237. inline Point Point::unit()
  238. {
  239.   GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  240.   val.pt[0] = pt[0] / m;
  241.   val.pt[1] = pt[1] / m;
  242.   val.pt[2] = pt[2] / m;
  243.   return val;
  244. }
  245.  
  246. inline void Point::unitize()
  247. {
  248.   GLfloat m = sqrt(pt[0]*pt[0] + pt[1]*pt[1] + pt[2]*pt[2]);
  249.   pt[0] /= m;
  250.   pt[1] /= m;
  251.   pt[2] /= m;
  252. }
  253.  
  254. inline Point Point::scale(Point p) 
  255. {
  256.   val.pt[0] = pt[0] * p.pt[0];
  257.   val.pt[1] = pt[1] * p.pt[1];
  258.   val.pt[2] = pt[2] * p.pt[2];
  259.   return val;
  260. }
  261.  
  262. inline Point Point::rotate(Point axis, GLfloat angle)
  263. {
  264.   return rotate(axis, cos(angle), sin(angle));
  265. }
  266.  
  267. inline Point Point::rotate(Point axis, GLfloat c, GLfloat s)
  268. {
  269.   float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  270.   float tx, ty;
  271.   
  272.   tx = t*x;
  273.   /* Taking advantage of inside info that this is a common case */
  274.   if (y == 0.0) {
  275.     val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(-s*z) + pt[2]*(tx*z);
  276.     val.pt[1] = pt[0]*(s*z) + pt[1]*c + pt[2]*(-s*x);
  277.     val.pt[2] = pt[0]*(tx*z) + pt[1]*s*x + pt[2]*(t*z*z + c);
  278.   } else {
  279.     ty = t*y;
  280.     val.pt[0] = pt[0]*(tx*x + c) + pt[1]*(tx*y - s*z) +
  281.       pt[2]*(tx*z + s*y);
  282.     val.pt[1] = pt[0]*(tx*y + s*z) + pt[1]*(ty*y + c) +
  283.       pt[2]*(ty*z - s*x);
  284.     val.pt[2] = pt[0]*(tx*z - s*y) + pt[1]*(ty*z + s*x) +
  285.       pt[2]*(t*z*z + c);
  286.   }
  287.   return val;
  288. }
  289.  
  290. inline void Point::rotate_self(Point axis, GLfloat c, GLfloat s)
  291. {
  292.   float Px, Py, Pz;
  293.   float x = axis.pt[0], y = axis.pt[1], z = axis.pt[2], t = 1.0 - c;
  294.   float tx, ty;
  295.   
  296.   tx = t*x;
  297.   Px = pt[0];
  298.   Py = pt[1];
  299.   Pz = pt[2];
  300.   /* Taking advantage of inside info that this is a common case */
  301.   if (!y) {
  302.     pt[0] = Px*(tx*x + c) +    Py*(-s*z) +     Pz*(tx*z);
  303.     pt[1] = Px*(s*z) +         Py*c +         Pz*(-s*x);
  304.     pt[2] = Px*(tx*z) +     Py*s*x +     Pz*(t*z*z + c);
  305.   } else {
  306.     ty = t*y;
  307.     pt[0] = Px*(tx*x + c) +     Py*(tx*y - s*z) +
  308.       Pz*(tx*z + s*y);
  309.     pt[1] = Px*(tx*y + s*z) +     Py*(ty*y + c) +
  310.       Pz*(ty*z - s*x);
  311.     pt[2] = Px*(tx*z - s*y) +     Py*(ty*z + s*x) +
  312.       Pz*(t*z*z + c);
  313.   }
  314. }  
  315.  
  316. inline void Point::glvertex() 
  317. {
  318.   glVertex3fv(pt);
  319. }
  320.  
  321. inline void Point::glnormal()
  322. {
  323.   glNormal3fv(pt);
  324. }
  325.  
  326. inline Point Point::project(Point proj_pt)
  327. {
  328.   GLfloat dirx = pt[0] - proj_pt.pt[0], 
  329.       diry = pt[1] - proj_pt.pt[1],
  330.       dirz = pt[2] - proj_pt.pt[2];
  331.   GLfloat t;
  332.  
  333.   if (fabs(dirz) < point_fudge) val = *this;
  334.   else {
  335.     t = -proj_pt.pt[2] / dirz;
  336.     val.pt[0] = proj_pt.pt[0] + dirx*t;
  337.     val.pt[1] = proj_pt.pt[1] + diry*t;
  338.     val.pt[2] = 0.0;
  339.   }
  340.   return val;
  341. }
  342.  
  343. // This naively assumes that proj_pt[z] != this->pt[z]
  344. inline void Point::project_self(Point proj_pt)
  345. {
  346.   GLfloat dirx = pt[0] - proj_pt.pt[0], 
  347.       diry = pt[1] - proj_pt.pt[1],
  348.       dirz = pt[2] - proj_pt.pt[2];
  349.   GLfloat t;
  350.  
  351.   t = -proj_pt.pt[2] / dirz;
  352.   pt[0] = proj_pt.pt[0] + dirx*t;
  353.   pt[1] = proj_pt.pt[1] + diry*t;
  354.   pt[2] = 0.0;
  355. }
  356.  
  357. inline void Point::project_self(GLfloat px, GLfloat py, GLfloat pz)
  358. {
  359.   GLfloat dirx = pt[0] - px, 
  360.   diry = pt[1] - py,
  361.   dirz = pt[2] - pz, t;
  362.  
  363.   t = -pz / dirz;
  364.   pt[0] = px + dirx*t;
  365.   pt[1] = py + diry*t;
  366.   pt[2] = 0.0;
  367. }
  368.  
  369. inline Point Point::project_direction(Point direction) {
  370.   GLfloat t;
  371.  
  372.   t = -pt[2] / direction.pt[2];
  373.   val.pt[0] = pt[0] + direction.pt[0]*t;
  374.   val.pt[1] = pt[1] + direction.pt[1]*t;
  375.   val.pt[2] = 0;
  376.   return val;
  377. }
  378.  
  379. inline Point Point::project_direction(GLfloat x, GLfloat y, GLfloat z) 
  380. {
  381.   GLfloat t;
  382.  
  383.   t = -pt[2] / z;
  384.   val.pt[0] = pt[0] + x*t;
  385.   val.pt[1] = pt[1] + y*t;
  386.   val.pt[2] = 0;
  387.   return val;
  388. }
  389.  
  390. inline void Point::compute_projected(GLfloat px, GLfloat py, GLfloat pz,
  391.                      GLfloat dx, GLfloat dy, GLfloat dz)
  392. {
  393.   GLfloat t = -pz / dz;
  394.   pt[0] = px + dx*t;
  395.   pt[1] = py + dy*t;
  396.   pt[2] = 0;
  397. }
  398.  
  399.  
  400. #undef POINT_EXTERN
  401.  
  402. #endif
  403.